# https://stackoverflow.com/questions/38098763/pyside-pyqt-how-to-make-set-qtablewidget-column-width-as-proportion-of-the-a
# todo 清零事件失败后 计数不应该清零
# 弹窗过于密集fbs编译后会闪退
# https://forum.qt.io/topic/64535/understanding-qmessagebox-exec-and-show/2
# https://doc.qt.io/qt-5/qdialog.html#modal-dialogs

import time

import logzero
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (
    QGridLayout,
    QGroupBox,
    QHBoxLayout,
    QHeaderView,
    QLabel,
    QMessageBox,
    QPushButton,
    QSplitter,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
    QWidget,
)

import mengy_spac800
import mengy_spac800_bt
from helpers.mengy_bytes_helper import bytes2Int, iecDateTimeStr
from qt_custom_widget.qt_TimerMessageBox import TimerMessageBox

logger = logzero.setup_logger("tabs.6.event")


class Tab_6_Event(QWidget):
    def __init__(self, serRecvDir, sendQueuePack, logger=logger):
        super().__init__()
        self.serRecvDir = serRecvDir
        self.sendQueuePack = sendQueuePack
        self.logger = logger
        self.initUI()
        self.lastEventlatestInfoBytes = None
        self.logger.info("this is tab6 event logger")
        self.setObjectName("tab6")
        layout = QVBoxLayout(self)
        splitterV = QSplitter(Qt.Vertical)
        splitterV.addWidget(self.eventRmtGroupBox)  # 遥信事件 (历史)
        splitterV.addWidget(self.eventPrtGroupBox)  # 保护事件 (历史)
        layout.addWidget(splitterV)

    def initUI(self):
        """初始化显示构件"""
        self.createEvenRmtGroupBox()
        self.createEventPrtGroupBox()

    def createEvenRmtGroupBox(self):
        self.eventRmtIndex = 0
        self.eventRmtSum = 0
        self.eventRmtAskTime = time.time()
        self.eventRmtNumber = 0
        self.lastEventRmtInfoBytes = None

        self.eventRmtGroupBox = QGroupBox("遥信事件(历史)")
        eventRmtLayout = QGridLayout()
        eventRmtLayout.setSpacing(0)
        eventRmtLayout.setContentsMargins(0, 0, 0, 0)
        self.eventRmtTW = QTableWidget()
        self.eventRmtTW.setRowCount(1)
        self.eventRmtTW.setColumnCount(4)
        self.eventRmtTW.setSortingEnabled(True)
        self.eventRmtTW.setEditTriggers(QTableWidget.NoEditTriggers)
        self.eventRmtTW.setHorizontalHeaderLabels(("序号", "日期时间", "开入", "类型"))
        self.eventRmtTW.verticalHeader().hide()
        header = self.eventRmtTW.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.Stretch)
        header.setSectionResizeMode(3, QHeaderView.Stretch)
        self.eventRmtClrBtn = QPushButton("清空表格")
        self.eventRmtClrBtn.clicked.connect(self.dealEventGroupButton)
        self.eventRmtRstBtn = QPushButton("事件清零")
        self.eventRmtRstBtn.clicked.connect(self.dealEventGroupButton)
        self.eventRmtSumLabel = QLabel("0")
        subLayout = QHBoxLayout()
        subLayout.addWidget(self.eventRmtClrBtn)
        subLayout.addWidget(self.eventRmtRstBtn)
        subLayout.addWidget(QLabel("事件总数:"))
        subLayout.addWidget(self.eventRmtSumLabel)
        subLayout.addStretch(1)
        eventRmtLayout.addWidget(self.eventRmtTW, 0, 0)
        eventRmtLayout.addLayout(subLayout, 1, 0)
        self.eventRmtGroupBox.setLayout(eventRmtLayout)

    def createEventPrtGroupBox(self):
        self.eventPrtIndex = 0
        self.eventPrtSum = 0
        self.eventPrtAskTime = time.time()
        self.eventPrtNumber = 0
        self.lastEventPrtInfoBytes = None

        self.eventPrtGroupBox = QGroupBox("保护事件(历史)")
        eventPrtLayout = QGridLayout()
        eventPrtLayout.setSpacing(0)
        eventPrtLayout.setContentsMargins(0, 0, 0, 0)
        self.eventPrtTW = QTableWidget()
        self.eventPrtTW.setRowCount(1)
        self.eventPrtTW.setColumnCount(17)
        self.eventPrtTW.setSortingEnabled(True)
        self.eventPrtTW.setEditTriggers(QTableWidget.NoEditTriggers)
        self.eventPrtTW.setHorizontalHeaderLabels(
            (
                "序号",
                "日期时间",
                "动作类型",
                "动作值",
                "Ia",
                "Ib",
                "Ic",
                "Uab",
                "Ubc",
                "Uca",
                "Ix",
                "Ux",
                "I0",
                "I1",
                "I2",
                "过热",
                "反时限",
            )
        )
        self.eventPrtTW.verticalHeader().hide()
        header = self.eventPrtTW.horizontalHeader()
        header.setMinimumSectionSize(35)
        header.setDefaultSectionSize(35)
        for i in (1, 2, 3):
            header.setSectionResizeMode(i, QHeaderView.ResizeToContents)
        for i in range(4, 17):
            header.setSectionResizeMode(i, QHeaderView.Stretch)

        self.eventPrtClrBtn = QPushButton("清空表格")
        self.eventPrtClrBtn.clicked.connect(self.dealEventGroupButton)
        self.eventPrtRstBtn = QPushButton("事件清零")
        self.eventPrtRstBtn.clicked.connect(self.dealEventGroupButton)
        self.eventPrtSumLabel = QLabel("0")
        subLayout = QHBoxLayout()
        subLayout.addWidget(self.eventPrtClrBtn)
        subLayout.addWidget(self.eventPrtRstBtn)
        subLayout.addWidget(QLabel("事件总数:"))
        subLayout.addWidget(self.eventPrtSumLabel)
        subLayout.addStretch(1)
        eventPrtLayout.addWidget(self.eventPrtTW, 0, 0)
        eventPrtLayout.addLayout(subLayout, 1, 0)
        self.eventPrtGroupBox.setLayout(eventPrtLayout)

    def dealEventGroupButton(self):
        """按钮处理"""
        sender = self.sender()
        choice = QMessageBox.question(self, "警告", "执行->{}？".format(sender.text()), QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            if sender is self.eventRmtClrBtn:  # 清空遥信事件表格
                self.eventRmtTW.clearContents()
                self.eventRmtTW.setRowCount(1)
            elif sender is self.eventPrtClrBtn:  # 清空历史保护事件表格
                self.eventPrtTW.clearContents()
                self.eventPrtTW.setRowCount(1)
            elif sender is self.eventRmtRstBtn:  # 清零遥信事件
                self.sendQueuePack(funCode=0x06, start=0x0B23, value=0xFF00)
                # self.eventRmtIndex = 0
            elif sender is self.eventPrtRstBtn:  # 清零历史保护事件
                self.sendQueuePack(funCode=0x06, start=0x0B22, value=0xFF00)
                # self.eventPrtIndex = 0

    def getEventPrtInfo(self):
        """保护事件 历史"""
        raw = [self.serRecvDir.get(0x0950 + i) for i in range(23)]  # 历史保护事件信息
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)  # 历史保护事件信息
        if self.lastEventPrtInfoBytes == epb or epb[0] == 0:
            return
        if self.eventPrtNumber == epb[0] and self.eventPrtIndex < epb[0]:
            self.logger.info("skip the latest new prt epb {}".format(epb))
        else:
            self.logger.info("get new prt epb {}".format(epb))
            self.eventPrtTW.setSortingEnabled(False)
            for i in range(self.eventPrtTW.rowCount() - 1):
                it = self.eventPrtTW.item(i, 0)
                newNum = int(it.text()) + 1
                it.setText("{:03d}".format(newNum))
            self.eventPrtTW.insertRow(0)
            for i in range(17):
                if self.eventPrtTW.item(0, i) is None:
                    self.eventPrtTW.setItem(0, i, QTableWidgetItem(""))
                self.eventPrtTW.item(0, i).setTextAlignment(Qt.AlignCenter)
            # self.eventPrtTW.item(0, 0).setText("{:02d}".format(epb[0]))
            self.eventPrtTW.item(0, 0).setText("{:03d}".format(1))
            self.eventPrtTW.item(0, 1).setText(iecDateTimeStr(epb[6:10]))
            self.eventPrtTW.item(0, 2).setText(mengy_spac800.DO_PRT_TYPE_NAME[epb[1] - 1])
            specInfo, specIdx = mengy_spac800.eventPtrActDecode(epb[1:5])
            self.eventPrtTW.item(0, 3).setText(specInfo)
            self.eventPrtTW.item(0, 4 + specIdx).setBackground(QColor("#f93b42"))
            for i, t in enumerate(mengy_spac800.eventPtrDetailDecode(epb[10:23])):
                self.eventPrtTW.item(0, 4 + i).setText(t)
            self.eventPrtTW.setSortingEnabled(True)
            self.logger.info("self.eventPrtTW.rowCount() {}".format(self.eventPrtTW.rowCount()))
        self.lastEventPrtInfoBytes = epb
        self.eventPrtIndex = epb[0] + 1
        # self.eventPrtTW.resizeColumnsToContents()

    def getEventRmtInfo(self):
        """遥信事件 历史"""
        raw = tuple(self.serRecvDir.get(i) for i in range(0x0A00, 0x0A07 + 1))  # 遥信事件信息
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)  # 遥信事件信息
        if self.lastEventRmtInfoBytes == epb or epb[0] == 0:
            return
        if self.eventRmtNumber == epb[0] and self.eventRmtIndex < epb[0]:
            self.logger.info("skip the latest new rmt epb {}".format(epb))
        else:
            self.logger.info("get new rmt epb {}".format(epb))
            self.eventRmtTW.setSortingEnabled(False)
            for i in range(self.eventRmtTW.rowCount() - 1):
                it = self.eventRmtTW.item(i, 0)
                newNum = int(it.text()) + 1
                it.setText("{:03d}".format(newNum))
            self.eventRmtTW.insertRow(0)
            for i in range(4):
                if self.eventRmtTW.item(0, i) is None:
                    self.eventRmtTW.setItem(0, i, QTableWidgetItem(""))
                self.eventRmtTW.item(0, i).setTextAlignment(Qt.AlignCenter)
            # self.eventRmtTW.item(0, 0).setText("{:02d}".format(epb[0]))
            self.eventRmtTW.item(0, 0).setText("{:03d}".format(1))
            self.eventRmtTW.item(0, 1).setText(iecDateTimeStr(epb[4:8]))
            diFuncIndex = bytes2Int(
                self.serRecvDir.get(0x030D + epb[1] - 1, bytes([len(mengy_spac800.DI_FUNC_TYPE)]))
            )  # 开入功能定义
            if diFuncIndex < len(mengy_spac800.DI_FUNC_TYPE):
                self.eventRmtTW.item(0, 2).setText(
                    "(开入{:2d}) {}".format(epb[1], mengy_spac800.DI_FUNC_TYPE[diFuncIndex])
                )
            else:
                self.eventRmtTW.item(0, 2).setText("(开入{:2d}) 数据异常".format(epb[1]))
            if epb[2] == 0x0000:
                self.eventRmtTW.item(0, 3).setText("合->分")
                self.eventRmtTW.item(0, 3).setBackground(QColor("#3af947"))
            else:
                self.eventRmtTW.item(0, 3).setText("分->合")
                self.eventRmtTW.item(0, 3).setBackground(QColor("#f93a3a"))
            self.eventRmtTW.setSortingEnabled(True)
            self.logger.info("self.eventRmtTW.rowCount() {}".format(self.eventRmtTW.rowCount()))
        self.lastEventRmtInfoBytes = epb
        self.eventRmtIndex = epb[0] + 1
        # self.eventRmtTW.resizeColumnsToContents()

    def getEventLatestInfo(self):
        """保护事件 最新"""
        raw = tuple(self.serRecvDir.get(i) for i in range(0x0920, 0x0929 + 1))
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)
        if self.lastEventlatestInfoBytes != epb and epb[0] != 0:
            self.logger.info("get new latest prt epb {}".format(epb))
            datetimeStr = iecDateTimeStr(epb[6:10])
            prtName = mengy_spac800.DO_PRT_TYPE_NAME[epb[1] - 1]
            actStr = mengy_spac800.eventPtrActDecode(epb[1:5])[0]
            self.lastEventlatestInfoBytes = epb
            QTimer.singleShot(250, lambda: self.sendQueuePack(funCode=0x06, start=0x0912, value=epb[0]))
            messageBox = TimerMessageBox(parent=self, timeout=10)
            messageBox.setIcon(QMessageBox.Warning)
            messageBox.setWindowTitle("保护告警: {}".format(prtName))
            # messageBox.setInformativeText("".format(datetimeStr))
            messageBox.setText("{}\n\n日期时间:\n{}\n\n动作值:\n{}".format(prtName, datetimeStr, actStr))
            messageBox.setStandardButtons(QMessageBox.Ok)
            messageBox.show()

    def updateEventRmtSum(self):
        """更新遥信事件总数"""
        if self.serRecvDir.get(0x0901) is not None:
            rmtSum = bytes2Int(self.serRecvDir[0x0901])
            self.eventRmtSumLabel.setText(str(rmtSum))
            self.eventRmtSum = rmtSum

    def updateEventRmtNumberIndex(self):
        """更新遥信事件编号"""
        if self.serRecvDir.get(0x0903) is not None:
            rmtNumber = bytes2Int(self.serRecvDir[0x0903])
            if self.eventRmtNumber != rmtNumber:
                self.logger.info(
                    "reset prt event sum {} lastest number {} --> {}".format(
                        self.eventRmtSum, self.eventRmtNumber, rmtNumber
                    )
                )
                self.eventRmtNumber = rmtNumber
                if self.eventRmtIndex == 0:
                    self.eventRmtIndex = self.eventRmtNumber - self.eventRmtSum + 1

    def eventRmtSendUpdate(self):
        """发送更新报文"""
        if (
            self.eventRmtIndex > 0
            and self.eventRmtIndex <= self.eventRmtNumber
            and time.time() - self.eventRmtAskTime > 0.5
        ):
            self.logger.info(
                "遥信事件总数 {} 下个读取序号 {} / {}".format(self.eventRmtSum, self.eventRmtIndex, self.eventRmtNumber)
            )
            self.sendQueuePack(funCode=0x06, start=0x0911, value=self.eventRmtIndex)
            self.sendQueuePack(funCode=0x03, start=0x0A00, length=8)
            self.eventRmtAskTime = time.time()
        elif self.eventRmtIndex > self.eventRmtNumber + 1:
            self.eventRmtIndex = self.eventRmtNumber + 1
        elif self.eventRmtIndex + 100 < self.eventRmtNumber:
            self.eventRmtIndex = self.eventRmtNumber + 1 - 100

    # 历史保护事件
    def updateEventPrtSum(self):
        """更新历史保护事件总数"""
        if self.serRecvDir.get(0x0900) is not None:
            prtSum = bytes2Int(self.serRecvDir[0x0900])
            self.eventPrtSumLabel.setText(str(prtSum))
            self.eventPrtSum = prtSum

    def updateEventPrtNumberIndex(self):
        """更新历史保护事件编号"""
        if self.serRecvDir.get(0x0902) is not None:
            prtNumber = bytes2Int(self.serRecvDir[0x0902])
            if self.eventPrtNumber != prtNumber:
                self.logger.info(
                    "reset prt event sum {} lastest number {} --> {}".format(
                        self.eventPrtSum, self.eventPrtNumber, prtNumber
                    )
                )
                self.eventPrtNumber = prtNumber
                if self.eventPrtIndex == 0:
                    self.eventPrtIndex = self.eventPrtNumber - self.eventPrtSum + 1

    def eventPrtSendUpdate(self):
        """发送更新报文"""
        if (
            self.eventPrtIndex > 0
            and self.eventPrtIndex <= self.eventPrtNumber
            and time.time() - self.eventPrtAskTime > 0.5
        ):
            self.logger.info(
                "历史保护事件总数 {} 下个读取序号 {} / {}".format(self.eventPrtSum, self.eventPrtIndex, self.eventPrtNumber)
            )
            self.sendQueuePack(funCode=0x06, start=0x0910, value=self.eventPrtIndex)
            self.sendQueuePack(funCode=0x03, start=0x0950, length=23)
            self.eventPrtAskTime = time.time()
        elif self.eventPrtIndex > self.eventPrtNumber + 1:
            self.eventPrtIndex = self.eventPrtNumber + 1
        elif self.eventPrtIndex + 100 < self.eventPrtNumber + 1:
            self.eventPrtIndex = self.eventPrtNumber + 1 - 100

    def updateBySerialRecvBuff(self, changeAddrList):
        """数据缓存发生变化时需要刷新部分"""
        pass

    def updateByTimer(self, timeout=1):
        pass

    def updateUnconditional(self):
        """无条件刷新界面显示部分"""
        self.getEventLatestInfo()
        # 遥信事件
        self.updateEventRmtSum()  # 遥信事件总数
        self.updateEventRmtNumberIndex()  # 遥信事件编号
        self.eventRmtSendUpdate()  # 发送遥信事件读取报文
        self.getEventRmtInfo()  # 更新遥信事件表格
        # 历史保护事件
        self.updateEventPrtSum()  # 历史保护事件总数
        self.updateEventPrtNumberIndex()  # 历史保护事件编号
        self.eventPrtSendUpdate()  # 发送历史保护事件读取报文
        self.getEventPrtInfo()  # 更新历史保护事件表格

    def updateWhole(self):
        """更新全体显示构件"""
        pass


class Tab_6_Event_BT(Tab_6_Event):
    def createEventPrtGroupBox(self):
        self.eventPrtIndex = 0
        self.eventPrtSum = 0
        self.eventPrtAskTime = time.time()
        self.eventPrtNumber = 0
        self.lastEventPrtInfoBytes = None

        self.eventPrtGroupBox = QGroupBox("保护事件(历史)")
        eventPrtLayout = QGridLayout()
        eventPrtLayout.setSpacing(0)
        eventPrtLayout.setContentsMargins(0, 0, 0, 0)
        self.eventPrtTW = QTableWidget()
        self.eventPrtTW.setRowCount(1)
        self.eventPrtTW.setColumnCount(14)
        self.eventPrtTW.setSortingEnabled(True)
        self.eventPrtTW.setEditTriggers(QTableWidget.NoEditTriggers)
        self.eventPrtTW.setHorizontalHeaderLabels(
            ("序号", "日期时间", "动作类型", "动作值", "Uab1", "Ubc1", "Uca1", "Uab2", "Ubc2", "Uca2", "Ix1", "Ux1", "Ix2", "Ux2")
        )
        self.eventPrtTW.verticalHeader().hide()
        header = self.eventPrtTW.horizontalHeader()
        header.setMinimumSectionSize(35)
        header.setDefaultSectionSize(35)
        for i in (1, 2, 3):
            header.setSectionResizeMode(i, QHeaderView.ResizeToContents)
        for i in range(4, 14):
            header.setSectionResizeMode(i, QHeaderView.Stretch)

        self.eventPrtClrBtn = QPushButton("清空表格")
        self.eventPrtClrBtn.clicked.connect(self.dealEventGroupButton)
        self.eventPrtRstBtn = QPushButton("事件清零")
        self.eventPrtRstBtn.clicked.connect(self.dealEventGroupButton)
        self.eventPrtSumLabel = QLabel("0")
        subLayout = QHBoxLayout()
        subLayout.addWidget(self.eventPrtClrBtn)
        subLayout.addWidget(self.eventPrtRstBtn)
        subLayout.addWidget(QLabel("事件总数:"))
        subLayout.addWidget(self.eventPrtSumLabel)
        subLayout.addStretch(1)
        eventPrtLayout.addWidget(self.eventPrtTW, 0, 0)
        eventPrtLayout.addLayout(subLayout, 1, 0)
        self.eventPrtGroupBox.setLayout(eventPrtLayout)

    def getEventPrtInfo(self):
        """保护事件 历史"""
        raw = [self.serRecvDir.get(0x0950 + i) for i in range(20)]  # 历史保护事件信息
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)  # 历史保护事件信息
        if self.lastEventPrtInfoBytes == epb or epb[0] == 0:
            return
        if self.eventPrtNumber == epb[0] and self.eventPrtIndex < epb[0]:
            self.logger.info("skip the latest new prt epb {}".format(epb))
        else:
            self.logger.info("get new prt epb {}".format(epb))
            self.eventPrtTW.setSortingEnabled(False)
            for i in range(self.eventPrtTW.rowCount() - 1):
                it = self.eventPrtTW.item(i, 0)
                newNum = int(it.text()) + 1
                it.setText("{:03d}".format(newNum))
            self.eventPrtTW.insertRow(0)
            for i in range(14):
                if self.eventPrtTW.item(0, i) is None:
                    self.eventPrtTW.setItem(0, i, QTableWidgetItem(""))
                self.eventPrtTW.item(0, i).setTextAlignment(Qt.AlignCenter)
            # self.eventPrtTW.item(0, 0).setText("{:02d}".format(epb[0]))
            self.eventPrtTW.item(0, 0).setText("{:03d}".format(1))
            self.eventPrtTW.item(0, 1).setText(iecDateTimeStr(epb[6:10]))
            self.eventPrtTW.item(0, 2).setText(mengy_spac800_bt.PRT_STATUS_TYPE_NAME[epb[1] - 1])
            specInfo, specIdx = mengy_spac800_bt.eventPtrActDecode(epb[1:5])
            self.eventPrtTW.item(0, 3).setText(specInfo)
            self.eventPrtTW.item(0, 4 + specIdx).setBackground(QColor("#f93b42"))
            for i, t in enumerate(mengy_spac800_bt.eventPtrDetailDecode(epb[10:20])):
                self.eventPrtTW.item(0, 4 + i).setText(t)
            self.eventPrtTW.setSortingEnabled(True)
            self.logger.info("self.eventPrtTW.rowCount() {}".format(self.eventPrtTW.rowCount()))
        self.lastEventPrtInfoBytes = epb
        self.eventPrtIndex = epb[0] + 1
        # self.eventPrtTW.resizeColumnsToContents()

    def getEventRmtInfo(self):
        """遥信事件 历史"""
        raw = tuple(self.serRecvDir.get(i) for i in range(0x0A00, 0x0A07 + 1))  # 遥信事件信息
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)  # 遥信事件信息
        if self.lastEventRmtInfoBytes == epb or epb[0] == 0:
            return
        if self.eventRmtNumber == epb[0] and self.eventRmtIndex < epb[0]:
            self.logger.info("skip the latest new rmt epb {}".format(epb))
        else:
            self.logger.info("get new rmt epb {}".format(epb))
            self.eventRmtTW.setSortingEnabled(False)
            for i in range(self.eventRmtTW.rowCount() - 1):
                it = self.eventRmtTW.item(i, 0)
                newNum = int(it.text()) + 1
                it.setText("{:03d}".format(newNum))
            self.eventRmtTW.insertRow(0)
            for i in range(4):
                if self.eventRmtTW.item(0, i) is None:
                    self.eventRmtTW.setItem(0, i, QTableWidgetItem(""))
                self.eventRmtTW.item(0, i).setTextAlignment(Qt.AlignCenter)
            # self.eventRmtTW.item(0, 0).setText("{:02d}".format(epb[0]))
            self.eventRmtTW.item(0, 0).setText("{:03d}".format(1))
            self.eventRmtTW.item(0, 1).setText(iecDateTimeStr(epb[4:8]))
            diFuncIndex = bytes2Int(
                self.serRecvDir.get(0x030D + epb[1] - 1, bytes([len(mengy_spac800_bt.DI_FUNC_TYPE)]))
            )  # 开入功能定义
            if diFuncIndex < len(mengy_spac800_bt.DI_FUNC_TYPE):
                self.eventRmtTW.item(0, 2).setText(
                    "(开入{:2d}) {}".format(epb[1], mengy_spac800_bt.DI_FUNC_TYPE[diFuncIndex])
                )
            else:
                self.eventRmtTW.item(0, 2).setText("(开入{:2d}) 数据异常".format(epb[1]))
            if epb[2] == 0x0000:
                self.eventRmtTW.item(0, 3).setText("合->分")
                self.eventRmtTW.item(0, 3).setBackground(QColor("#3af947"))
            else:
                self.eventRmtTW.item(0, 3).setText("分->合")
                self.eventRmtTW.item(0, 3).setBackground(QColor("#f93a3a"))
            self.eventRmtTW.setSortingEnabled(True)
            self.logger.info("self.eventRmtTW.rowCount() {}".format(self.eventRmtTW.rowCount()))
        self.lastEventRmtInfoBytes = epb
        self.eventRmtIndex = epb[0] + 1
        # self.eventRmtTW.resizeColumnsToContents()

    def getEventLatestInfo(self):
        """保护事件 最新"""
        raw = tuple(self.serRecvDir.get(i) for i in range(0x0920, 0x0929 + 1))
        if any((i is None for i in raw)):
            return
        epb = tuple(bytes2Int(i) for i in raw)
        if self.lastEventlatestInfoBytes != epb and epb[0] != 0:
            self.logger.info("get new latest prt epb {}".format(epb))
            datetimeStr = iecDateTimeStr(epb[6:10])
            prtName = mengy_spac800_bt.PRT_STATUS_TYPE_NAME[epb[1] - 1]
            actStr = mengy_spac800_bt.eventPtrActDecode(epb[1:5])[0]
            self.lastEventlatestInfoBytes = epb
            QTimer.singleShot(250, lambda: self.sendQueuePack(funCode=0x06, start=0x0912, value=epb[0]))
            messageBox = TimerMessageBox(parent=self, timeout=10)
            messageBox.setIcon(QMessageBox.Warning)
            messageBox.setWindowTitle("保护告警: {}".format(prtName))
            # messageBox.setInformativeText("".format(datetimeStr))
            messageBox.setText("{}\n\n日期时间:\n{}\n\n动作值:\n{}".format(prtName, datetimeStr, actStr))
            messageBox.setStandardButtons(QMessageBox.Ok)
            messageBox.show()
